<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CamelUpStateCaculator</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/antd@4.18.5/dist/antd.min.css" />
    <script src="https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/antd@4.18.5/dist/antd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
    <style>
      * {
        box-sizing: border-box;
      }
      html,
      body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #app {
        width: 100%;
        height: 100%;
      }
      .container {
        padding: 8px;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        overflow: auto;
      }
      .ant-divider::before {
        top: 0 !important;
      }
      .ant-divider::after {
        top: 0 !important;
      }
      .box {
        display: flex;
        gap: 12px;
        align-items: center;
        width: 100%;
        border: 1px solid #ccc;
      }
      .box-serial {
        width: 16px;
        text-align: right;
      }
      .camel-selector,
      .trap-selector {
        flex-grow: 1;
      }
      .loading {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: rgba(0, 0, 0, 0.6);
      }
    </style>
  </head>
  <body>
    <div id="app"></div>
    <script src="//cdn.jsdelivr.net/npm/eruda"></script>
    <script>
      eruda.init();
    </script>
    <script src="./constants.js"></script>
    <script>
      const { createElement, useState, useCallback } = React;
      const { Select, Tag, Table, Radio, Checkbox, Divider, Spin, Button } = antd;

      const tagRender = (props) => {
        return createElement(
          Tag,
          {
            ...props,
            color: CAMEL_COLOR[props.value],
            style: {
              margin: '0 4px',
            },
          },
          props.label,
        );
      };

      const App = () => {
        const [camelIndex, setCamelIndex] = useState({
          0: [CAMEL.red],
          1: [CAMEL.yellow],
          2: [CAMEL.green],
          3: [CAMEL.blue],
          4: [CAMEL.purple],
          15: [CAMEL.white, CAMEL.black],
        });
        const [trapIndex, setTrapIndex] = useState({});
        const [result, setResult] = useState({});
        const [availableDices, setAvailableDices] = useState([
          DICE.red,
          DICE.yellow,
          DICE.green,
          DICE.blue,
          DICE.purple,
          DICE.whiteBlack,
        ]);
        const [loading, setLoading] = useState(false);

        const calculate = useCallback(() => {
          console.log(camelIndex);
          if (Object.values(camelIndex).reduce((pre, cur) => _.difference(pre, cur), Object.keys(CAMEL)).length !== 0) {
            alert('有骆驼未选择');
            return;
          }

          const worker = new Worker('./iterator.js');
          worker.onmessage = (e) => {
            const { stateCount, totalState } = e.data;
            console.log('stateCount', JSON.parse(JSON.stringify(stateCount)));
            console.log('totalState', totalState);
            Object.values(stateCount).forEach((count) => {
              count[1] = (count[1] / totalState).toFixed(2);
              count[2] = (count[2] / totalState).toFixed(2);
              count[5] = (count[5] / totalState).toFixed(2);
            });
            setResult(stateCount);
            setLoading(false);
            worker.terminate();
          };
          worker.onerror = (e) => {
            console.error(e);
            setLoading(false);
            worker.terminate();
          };
          setLoading(true);
          worker.postMessage({
            initState: camelIndex,
            trapIndex,
            availableDices,
            ratio: 1,
          });
        }, [camelIndex, trapIndex, availableDices]);

        return createElement(
          'div',
          {
            className: 'container',
          },
          [
            createElement(
              Button,
              {
                type: 'primary',
                onClick: calculate,
              },
              '计算',
            ),
            createElement(Table, {
              className: 'result',
              dataSource: PLAYER_CAMEL.map((key) => {
                return {
                  id: key,
                  name: CAMEL_NAME[key],
                  ...result[key],
                };
              }),
              rowKey: (row) => row.id,
              pagination: false,
              bordered: true,
              columns: [
                {
                  title: 'name',
                  render: (row) => row.name,
                },
                {
                  title: '1',
                  render: (row) => row[1] ?? 'TBD',
                },
                {
                  title: '2',
                  render: (row) => row[2] ?? 'TBD',
                },
                {
                  title: '5',
                  render: (row) => row[5] ?? 'TBD',
                },
              ],
            }),
            createElement(Divider, null, '可用的骰子'),
            createElement(
              'div',
              {},
              createElement(Checkbox.Group, {
                options: [
                  {
                    label: '红',
                    value: DICE.red,
                  },
                  {
                    label: '黄',
                    value: DICE.yellow,
                  },
                  {
                    label: '绿',
                    value: DICE.green,
                  },
                  {
                    label: '蓝',
                    value: DICE.blue,
                  },
                  {
                    label: '紫',
                    value: DICE.purple,
                  },
                  {
                    label: '黑白',
                    value: DICE.whiteBlack,
                  },
                ],
                defaultValue: availableDices,
                onChange: (values) => {
                  setAvailableDices(values);
                },
              }),
            ),
            createElement(Divider, null, '地图'),
            createElement(
              'div',
              {
                className: 'map',
              },
              [
                new Array(MAP_LENGTH).fill(null).map((_, boxIndex) => {
                  const options = Object.values(CAMEL)
                    .filter((item) => {
                      const index = Object.keys(camelIndex).find((i) => camelIndex[i].includes(item));
                      return !index || index === boxIndex.toString();
                    })
                    .map((key) => {
                      return createElement(
                        Select.Option,
                        {
                          key,
                          value: key,
                        },
                        CAMEL_NAME[key],
                      );
                    });

                  return createElement(
                    'div',
                    {
                      className: 'box',
                    },
                    [
                      createElement(
                        'div',
                        {
                          className: 'box-serial',
                        },
                        boxIndex + 1,
                      ),
                      createElement(
                        Select,
                        {
                          className: 'camel-selector',
                          mode: 'multiple',
                          tagRender,
                          allowClear: true,
                          disabled: options.length === 0 || trapIndex[boxIndex],
                          showSearch: false,
                          defaultValue: camelIndex[boxIndex],
                          onChange: (value) => {
                            setCamelIndex({
                              ...camelIndex,
                              [boxIndex]: value,
                            });
                          },
                        },
                        options,
                      ),
                      createElement(
                        Radio.Group,
                        {
                          className: 'trap-selector',
                          defaultValue: 0,
                          disabled: camelIndex[boxIndex]?.length > 0,
                          onChange: ({ target: { value } }) => {
                            if (value !== 0) {
                              setCamelIndex({
                                ...camelIndex,
                                [boxIndex]: [],
                              });
                            }
                            setTrapIndex({
                              ...trapIndex,
                              [boxIndex]: value,
                            });
                          },
                        },
                        [
                          createElement(
                            Radio,
                            {
                              value: 0,
                            },
                            '无',
                          ),
                          createElement(
                            Radio,
                            {
                              value: TRAP.plus,
                            },
                            '+1',
                          ),
                          createElement(
                            Radio,
                            {
                              value: TRAP.minus,
                            },
                            '-1',
                          ),
                        ],
                      ),
                    ],
                  );
                }),
              ],
            ),
            loading &&
              createElement(
                'div',
                {
                  className: 'loading',
                },
                createElement(Spin, {
                  size: 'large',
                }),
              ),
          ],
        );
      };

      ReactDOM.render(createElement(App), document.getElementById('app'));
    </script>
  </body>
</html>
